package libs.game.sokoban;

import libs.game.*;

/**
 *              It represents a path in game plan where the person can go.
 *
 * @author      Jan Papousek
 * @version     2009-03-12
 */
public class PersonPath extends AbstractPath {

    /**
     *          It creates a path where the person can go.
     *
     * @param   gamePlan    Game Plan.
     */
    public PersonPath(SokobanGamePlan gamePlan) {
        if (gamePlan == null) {
            throw new NullPointerException("Argument 'gamePlan' is null.");
        }
        path = new Integer[gamePlan.rows()][gamePlan.columns()];
        compute(gamePlan,gamePlan.getPersonCoords(), 0);
    }

    private void compute(SokobanGamePlan gamePlan,Coordinates field, int value) {
        if ((field.getX() < 0) || (field.getY() < 0)) {
            return;
        }
        if ((field.getX() >= gamePlan.columns()) || (field.getY() >= gamePlan.rows())) {
            return;
        }
        if ((gamePlan.getField(field) != SokobanGamePlan.FIELD_GOAL) && (gamePlan.getField(field) != SokobanGamePlan.FIELD_EMPTY) && (value != 0)) {
            return;
        }
        if (path[field.getY()][field.getX()] != null) {
            return;
        }
        numOfPathFields++;
        this.path[field.getY()][field.getX()] = value;
        compute(gamePlan, new Coordinates(field.getX() + 1, field.getY()), value + 1);
        compute(gamePlan, new Coordinates(field.getX() - 1, field.getY()), value + 1);
        compute(gamePlan, new Coordinates(field.getX(), field.getY() + 1), value + 1);
        compute(gamePlan, new Coordinates(field.getX(), field.getY() - 1), value + 1);
    }

}
